home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / usenet / volume6 / cubes2 / part03 < prev    next >
Encoding:
Internet Message Format  |  1989-07-06  |  54.5 KB

  1. Path: uunet!tektronix!tekgen!tekred!games
  2. From: games@tekred.CNA.TEK.COM
  3. Newsgroups: comp.sources.games
  4. Subject: v06i061:  cubes2 - a networked dice game (version 5.1), Part03/08
  5. Message-ID: <3902@tekred.CNA.TEK.COM>
  6. Date: 27 Apr 89 19:21:36 GMT
  7. Sender: billr@tekred.CNA.TEK.COM
  8. Lines: 1941
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: gmp@rayssdb.RAY.COM (Gregory M. Paris)
  12. Posting-number: Volume 6, Issue 61
  13. Archive-name: cubes2/Part03
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 3 (of 8)."
  24. # Contents:  cubes.long.6 moniker.c tempers.c
  25. # Wrapped by billr@saab on Thu Apr 27 12:13:36 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'cubes.long.6' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'cubes.long.6'\"
  29. else
  30. echo shar: Extracting \"'cubes.long.6'\" \(26844 characters\)
  31. sed "s/^X//" >'cubes.long.6' <<'END_OF_FILE'
  32. X.TH CUBES.LONG 6 "cubes 5.1" GMP "UNIX Gaming Manual"
  33. X.SH NAME
  34. Xcubes.long \- the nitty-gritty details of the game of cubes
  35. X.\"
  36. X.\" sccsid: @(#)cubes.long.6 5.1 (G.M. Paris) 89/01/22
  37. X.\"
  38. X.\"
  39. X.\"
  40. X.\"    cubes 5.1  Copyright 1988 Gregory M. Paris
  41. X.\"        Permission granted to redistribute on a no charge basis.
  42. X.\"        All other rights are reserved.
  43. X.\"
  44. X.\"
  45. X.SH SYNOPSIS
  46. X.B cubes
  47. X[
  48. X.BR \- [ F ]{ BS }
  49. X] [
  50. X.B \-s
  51. X] [
  52. X.BR \- { pw }
  53. X] [
  54. X.B \-g graphics
  55. X] [
  56. X.B \-f cubehist
  57. X] [
  58. X.B \-h cubehost
  59. X] [
  60. X.B cubename
  61. X]
  62. X.SH OVERVIEW
  63. X[ Note: This is the long and complicated manual page for
  64. X.IR cubes ,
  65. Xwhich exists for the purpose of detailing the finer points of the game.
  66. XIf you are a beginner at
  67. X.IR cubes ,
  68. Xthe shorter manual page,
  69. X.IR cubes (6),
  70. Xshould be all you need to start playing the game. ]
  71. X.PP
  72. XThe game of
  73. X.I cubes
  74. Xis a computer implementation of a dice game played with
  75. Xfive six-sided dice.
  76. XThe goal of the game is to be the first player to
  77. Xscore
  78. X.I Win Score
  79. Xpoints (usually 10,000).
  80. XPlayers take turns rolling the dice in the hopes of getting one or more
  81. Xof several scoring combinations.
  82. XA player can continue rolling as long as the previous roll produced
  83. Xa scoring combination.
  84. XFailing that,
  85. Xany points accumulated during the turn are lost and the player's turn ends.
  86. XBefore that happens,
  87. Xthe player may elect to quit rolling (prudently or cowardly),
  88. Xcausing the points accumulated during the turn
  89. Xto be added to the player's score.
  90. XIt takes about twenty minutes to play a single 10,000 point game.
  91. XContrary to what you might think by reading this manual page,
  92. X.I cubes
  93. Xis both easy to learn and easy to play.
  94. X.SH "BEGINNING A GAME"
  95. X.I Cubes
  96. Xis both a single-player and a multi-player game,
  97. Xwith the game logic implemented in a cube server,
  98. Xand player interaction via a client process, the
  99. X.I cubes
  100. Xprogram.
  101. XFor more than one person to play at a time,
  102. Xeach must each begin
  103. X.I cubes
  104. Xat nearly the same time, and must connect to the same server.
  105. X.PP
  106. XThere are two
  107. X.I cubes
  108. Xgame modes:
  109. X.I Standard
  110. Xand
  111. X.IR Blitz .
  112. XThe first corresponds to games played to 10,000 points;
  113. Xthe second to shorter games played to 7,500 points.
  114. XSupplying the
  115. X.B \-B
  116. Xor
  117. X.B \-S
  118. Xoption informs the server that you'd prefer to play
  119. X.I Blitz
  120. Xmode or
  121. X.I Standard
  122. Xmode games respectively.
  123. XThe
  124. X.B \-FB
  125. X.RI ( Force \  Blitz )
  126. Xor
  127. X.B \-FS
  128. X.RI ( Force \  Standard )
  129. Xoption informs the server that you will play only
  130. X.I Blitz
  131. Xor
  132. X.I Standard
  133. Xmode games respectively.
  134. XYour preference may be taken into account when the server
  135. Xdecides the mode for each game.
  136. XIf the server does not honor your preference
  137. Xand if you specified one of the forced preferences,
  138. Xthe server will reject you.
  139. XIf you do not supply a preference option,
  140. Xthe server assumes you have no preference.
  141. X.PP
  142. XIf
  143. X.I cubes
  144. Xis invoked with the
  145. X.B \-s
  146. X(spider mode) option,
  147. Xand if there are no humans already playing,
  148. Xthe program will hang,
  149. Xwaiting for another human to begin a game.
  150. X(You may wish to suspend
  151. X.I cubes
  152. Xat this point -- the program will alert you by
  153. Xringing your terminal bell when a game is about to begin.)\ 
  154. XIf you get tired of waiting for another player,
  155. Xyou can quit waiting and begin a game by typing the letter
  156. X.RB ` g '
  157. Xfor `go'.
  158. XYou also can quit waiting with an interrupt,
  159. Xwhich will cause
  160. X.I cubes
  161. Xto exit, with no penalty to your ranking.
  162. X.PP
  163. XWhen a person enters a game already in progress
  164. X(explained more fully below),
  165. X.I cubes
  166. Xwill add that person as a watcher.
  167. XThe watcher can join the game using
  168. X.RB ` g '
  169. Xfor `go'.
  170. XThis step can be skipped by supplying
  171. X.RB ` \-p '
  172. Xswitch on the command line, causing
  173. X.I cubes
  174. Xthe user to be added as a player, rather than as a watcher.
  175. X.PP
  176. XIf your terminal supports DEC or Zenith graphics mode,
  177. Xyou can tell
  178. X.I cubes
  179. Xto take advantage of the graphics when drawing the screen.
  180. X(This feature assumes that the
  181. X.RB ` as '
  182. Xand
  183. X.RB ` ae '
  184. Xtermcap capabilities describe how to put your terminal into and take it out of
  185. Xgraphics mode.)\ 
  186. XTo do this, supply the
  187. X.RB ` \-g \  graphics '
  188. Xoption on the command line, where
  189. X.B graphics
  190. Xis one of
  191. X.RB ` d '
  192. Xfor DEC graphics,
  193. Xor
  194. X.RB ` z '
  195. Xfor Zenith graphics.
  196. XThe
  197. X.B \-g
  198. Xoption need not be supplied if your terminal's termcap
  199. Xentry specifies the
  200. X.RB ` Cg '
  201. X.RI ( C ubes
  202. X.IR g raphics)
  203. Xstring capability to be a letter corresponding to
  204. Xone of the valid graphics types
  205. X.RB ( d 
  206. Xor
  207. X.BR z ).
  208. X.PP
  209. XAfter each completed game,
  210. X.I cubes
  211. Xappends a single line to the file ``.cubehist'' in
  212. Xyour home directory.
  213. XThe line provides a summary of what the game did to your
  214. Xstanding with regard to other players of
  215. X.IR cubes .
  216. XIf you wish to change the location of this file,
  217. Xyou may do so with the
  218. X.RB ` \-f \  cubehist '
  219. Xcommand line option,
  220. Xor with the
  221. X.B CUBEHIST
  222. Xenvironment variable.
  223. XThe command line option overrides the environment variable setting.
  224. XTo disable the feature entirely, specify a null filename.
  225. X.PP
  226. XThe
  227. X.I cubes
  228. Xprogram assumes that the server is on the same system as the player.
  229. XIf this is not so, the
  230. X.RB ` \-h \  cubehost '
  231. Xoption can be used to tell
  232. X.I cubes
  233. Xwhich system the server is running on.
  234. XIf you normally connect to a server on another system,
  235. Xyou may find it more convenient to set the
  236. X.B CUBEHOST
  237. Xenvironment variable to that system's name.
  238. X(The command line option overrides the environment variable.)
  239. X.PP
  240. XIf you'd like your name during the game
  241. Xto be something other than your login name,
  242. Xyou can supply a new name on the command line
  243. X(multi-word names need not be quoted).
  244. XIf you have a favorite name,
  245. Xyou can set the environment variable
  246. X.B CUBENAME
  247. Xto that value, which
  248. X.I cubes
  249. Xwill use when none is supplied on the command line.
  250. XIn either case,
  251. X.I cubes
  252. Xwill display only the first eighteen characters of the name.
  253. X.SH "PLAYING THE GAME"
  254. XThe rules of the game are described in more depth below.
  255. XFortunately, it is not necessary to understand the rules before playing
  256. X.IR cubes ,
  257. Xsince the cube server handles all that for you.
  258. XThe only thing to know before playing is what to do when prompted.
  259. X.PP
  260. XThe
  261. X.I cubes
  262. Xprogram will ask you only a few questions.
  263. XThe first question of each turn is
  264. X.PP
  265. X.B "    Ready to roll? [yxe]"
  266. X.PP
  267. Xwhich is asking you to make the first roll of your turn.
  268. XThe letters
  269. X.RB ` yxe '
  270. Xindicate that the three valid answers are
  271. X.RB ` y '
  272. Xfor yes (to roll), and
  273. X.RB ` x '
  274. Xto enter autopilot mode (see
  275. X.B AUTOPILOT
  276. Xbelow),
  277. X.RB ` e '
  278. Xfor exit, to quit the game (see
  279. X.B QUITTING EARLY
  280. Xbelow).
  281. XThe default if you type just a carriage return is yes.
  282. X.PP
  283. XThe second question, of the form
  284. X.PP
  285. X.B "    nnn saved, mmm showing; command? [rkhmabpxe]"
  286. X.PP
  287. Xis asking you whether you want to quit rolling or not,
  288. Xand if not, which dice you want to roll.
  289. XThe value of
  290. X.B nnn
  291. Xis the number of points you have from previous rolls.
  292. XThe value of
  293. X.B mmm
  294. Xis the number of points from the dice you just rolled.
  295. XIf you hold, the sum of
  296. X.B nnn
  297. Xand
  298. X.B mmm
  299. Xwill be added to your score.
  300. XTo hold, type
  301. X.RB ` h '
  302. Xand a carriage return.
  303. X.PP
  304. XIf you wish to roll again, you can type just a carriage return, and all
  305. Xnonscoring dice will be rerolled (or all dice, if they've all scored).
  306. XIf in addition to the nonscoring dice, you wish to roll some of the
  307. Xscoring dice, you can type
  308. X.RB ` r '
  309. Xfollowed by the die numbers.
  310. XThe
  311. X.RB ` r '
  312. Xis default, so you can omit it if you like (and you probably will).
  313. XAlso, if you omit the dice numbers, only the nonscoring dice will be rolled.
  314. XNote that the nonscoring dice always will be rolled,
  315. Xeven if you don't specify them explicitly,
  316. Xso there's really no point in doing so.
  317. X.PP
  318. XSometimes it may be more convenient to tell
  319. X.I cubes
  320. Xwhich dice you wish to keep rather than which dice you wish to roll.
  321. XTo do this,
  322. Xyou can type
  323. X.RB ` k '
  324. Xfollowed by a list of the dice you want to hold back.
  325. XIf no dice are specified, all scoring dice are kept and only nonscoring
  326. Xdice are rolled.
  327. X.PP
  328. XSome players find it advantageous to check the score file
  329. X(see
  330. X.B THE SCORE FILE
  331. Xbelow)
  332. Xbefore deciding whether to roll again or to hold.
  333. XFour commands are available for this purpose.
  334. XThey are
  335. X.RB ` m '
  336. Xfor my rank,
  337. X.RB ` a '
  338. Xfor above me,
  339. X.RB ` b '
  340. Xfor below me,
  341. Xand
  342. X.RB ` p < number >'
  343. Xfor player rank.
  344. XThese commands will cause
  345. X.I cubes
  346. Xto display the score file information for you,
  347. Xfor the player ranked immediately above you,
  348. Xfor the player ranked immediately below you,
  349. Xor for the selected player in the current game.
  350. X.PP
  351. XIf you are going to be temporarily interrupted,
  352. Xyou might want enter autopilot mode by answering
  353. Xwith
  354. X.RB ` x '.
  355. X.PP
  356. XYou also can type
  357. X.RB ` e '
  358. Xin response to this question,
  359. Xwhich will get you yet another question
  360. X.PP
  361. X.B "    Do you really want to quit the game? [ny]"
  362. X.PP
  363. Xthe default answer being
  364. X.RB ` n '
  365. Xfor no.
  366. XYou should read the section titled
  367. X.B QUITTING EARLY
  368. Xbefore you answer
  369. X.RB ` y '
  370. Xto this question.
  371. X.PP
  372. XAt the conclusion of a game,
  373. X.I cubes
  374. Xwill prompt with
  375. X.PP
  376. X.B "    Play another game? [ynmabp]"
  377. X.PP
  378. Xif you played in the last game, or if you were watching
  379. X.PP
  380. X.B "    Play in next game? [ynmabp]"
  381. X.PP
  382. Xeither of which is asking you if you'd like to play in the next game.
  383. XThere is no default answer to this question because it is too easy
  384. Xto confuse this prompt with the "Ready to roll?" prompt,
  385. Xwhich is answered almost invariably with a carriage return.
  386. XThe
  387. X.RB ` m ',
  388. X.RB ` a ',
  389. X.RB ` b ',
  390. Xand
  391. X.RB ` p '
  392. Xcommands, as described above, are available for use at this prompt.
  393. X.SH "SCORING COMBINATIONS"
  394. XThe following is a description of each of the
  395. X.I cubes
  396. Xscoring combinations.
  397. XBelow, the word ``face'' is used as shorthand for face value.
  398. XFor a one, the face value is ten,
  399. Xand for a joker (see
  400. X.I Joker
  401. Xbelow) the face value is thirty.
  402. XFor all other faces, the face value is the same as the number of spots
  403. Xon the face, that is, two for a two, three for a three, etc.
  404. X.IP Points 12
  405. XDescription
  406. X.IP "300 * face"
  407. X.I Five of a Kind
  408. Xis the only combination that includes previously held dice.
  409. X.I Five of a Kind
  410. Xis all five dice showing the same face.
  411. XThis combination can occur any time the dice are rolled
  412. X(if any held dice are showing the same face).
  413. XSince held dice are part of the new combination,
  414. Xto not be counted twice,
  415. Xthe points for the old combination(s) are forgotten.
  416. XAll five dice score.
  417. X.IP 1500/750
  418. XA
  419. X.I Straight
  420. Xis an uninterrupted sequence of
  421. Xfive numbers, either one through five or two through six.
  422. XAll five dice score.
  423. XIf previously held dice are used in making a
  424. X.IR Straight,
  425. Xit is worth 750 points.
  426. XOtherwise, if all five dice were rolled to produce the
  427. X.IR Straight,
  428. Xit is worth 1500 points.
  429. X.IP "200 * face"
  430. X.I Four of a Kind
  431. Xis four rolled dice showing the same face.
  432. XThis combination can occur only when four or five dice are rolled.
  433. XFour dice score.
  434. X.IP 400
  435. XA
  436. X.I Small Straight
  437. Xis an uninterrupted sequence of four numbers.
  438. XThe possibilities are one through four, two through five, or three through six.
  439. XThis combination can occur only when four or five dice are rolled.
  440. XFour dice score.
  441. X.IP "100 * face"
  442. X.I Three of a Kind
  443. Xis three rolled dice showing the same face.
  444. XThis combination can occur when three, four, or five dice are rolled.
  445. XThree dice score.
  446. X.IP 100
  447. XAny
  448. X.IR One ,
  449. Xnot part of another combination, is a scoring combination unto itself.
  450. XA
  451. X.I One
  452. Xcan occur at any time.
  453. XEach
  454. X.I One
  455. Xis a scoring die.
  456. X.IP 50
  457. XAny
  458. X.IR Five ,
  459. Xnot part of another combination, is a scoring combination unto itself.
  460. XA
  461. X.I Five
  462. Xcan occur at any time.
  463. XEach
  464. X.I Five
  465. Xis a scoring die.
  466. X.IP 0
  467. XAny
  468. X.IR Joker ,
  469. Xnot part of another combination, is a scoring combination unto itself,
  470. Xbut unlike the
  471. X.I One
  472. Xand
  473. X.IR Five ,
  474. Xa single
  475. X.I Joker
  476. Xis not worth any points. 
  477. XHowever, the face value of a
  478. X.I Joker
  479. Xis a whopping thirty, thus making
  480. X.IR Three ,
  481. X.IR Four ,
  482. Xand
  483. X.I Five of a Kind
  484. Xin
  485. X.I Jokers
  486. Xworth 3000, 6000, and 9000 points respectively.
  487. X.B Note:
  488. Xnot all cube servers will be configured to play
  489. X.I cubes
  490. Xwith dice that have
  491. X.I Jokers
  492. Xon them, and even if so configured,
  493. Xwill not play all games with such dice.
  494. XIf the game is to be played with
  495. X.I Joker
  496. Xdice, you will be notified before the game begins
  497. X(or when you enter, if the game is in progress).
  498. XYou may think of these dice as having thirteen sides,
  499. Xwith two of each of the faces one through six,
  500. Xand one
  501. X.I Joker
  502. Xface.
  503. X.SH "ROLLING THE DICE"
  504. XEach turn starts with the player rolling all five dice.
  505. XWhenever the dice are rolled, if no scoring combination appears,
  506. Xthe turn is over and any points accumulated during the turn are lost.
  507. XIf some dice score,
  508. Xthen the player can choose to roll again or to quit rolling.
  509. XWhen the player quits, the points accumulated during the turn are
  510. Xadded to the player's score.
  511. XThis is the only way to score points.
  512. X.PP
  513. XWhen rerolling, all nonscoring dice are always part of the reroll.
  514. XIf more than one scoring combination occurred on the prior roll,
  515. Xthe player also may choose to reroll some scoring dice,
  516. Xwith the restriction that at least one scoring combination must be held back.
  517. XWhen scoring dice are rerolled,
  518. Xthe points for the combinations they were part of are not added to
  519. Xthe accumulated turn points.
  520. X.PP
  521. XWhen all five dice score, either in a single roll or in multiple rolls,
  522. Xthe player may continue rolling with all five dice.
  523. XThis is the same as beginning the turn afresh,
  524. Xexcept that the turn points earned so far are retained (but are still
  525. Xvulnerable to being lost).
  526. X.PP
  527. XA player must quit rolling at some time to earn points on the scoreboard,
  528. Xbut there are two times when the player cannot quit.
  529. XThe first time is when the player has zero points, or in other words,
  530. Xis not yet on the scoreboard.
  531. XThe player must score at least 500 points in a turn to get
  532. X.I On Board
  533. Xand cannot quit before earning those points.
  534. XSimilarly, to get
  535. X.IR Off \  Board ,
  536. Xor cross the
  537. X.I Win Score
  538. Xline, the player needs at least 500 turn points.
  539. XThis threshold need be matched only when trying to cross
  540. X.I Win Score
  541. Xpoints;
  542. Xonce beyond, the player can quit with any number of turn points.
  543. X.SH "WINNING THE GAME"
  544. XA player with
  545. X.I Win Score
  546. Xpoints or more at the end of a round of
  547. Xturns is the winner, but only if that player's score exceeds
  548. Xthe next best score by a
  549. X.I Win Margin
  550. Xof 250 points.
  551. XWhile this condition is not met, play continues.
  552. X.I Cubes
  553. Xwill warn of a player's impending win.
  554. X.PP
  555. XNormally, 10,000 points is the
  556. X.IR Win \  Score ,
  557. Xor minimum score, needed to win a game.
  558. XOn some systems, however, the cube server may be configured
  559. Xto run in
  560. X.I Blitz
  561. Xmode during some parts of the day (usually working hours),
  562. Xor when all players with a preference desire to play in
  563. X.I Blitz
  564. Xmode.
  565. X(See
  566. X.IR cubeserver (6)
  567. Xfor more details.)
  568. XIn a
  569. X.I Blitz
  570. Xmode game,
  571. X.I Win Score
  572. Xwill be less than 10,000 points,
  573. Xusually 7,500 points (unless changed at compile time).
  574. XA reduced
  575. X.I Win Score
  576. Xmakes for shorter, but riskier games
  577. Xsince there's less time to catch up if you get behind,
  578. Xand also because entries made to the score file are
  579. Xscaled to 10,000 points \- thus making a loss by 500 points
  580. Xinto a recorded loss by 750 points, if
  581. X.I Win Score
  582. Xis 7,500 points.
  583. X(This effect cuts both ways, however, since a win
  584. Xis also scaled up to being a bigger win.)\ 
  585. XThe current
  586. X.I Win Score
  587. Xis always displayed on the screen,
  588. Xand is set only at the beginning of each game.
  589. X.SH "COMPUTER PLAYERS"
  590. XSince it would be pointless to play the game alone,
  591. Xthe cube server provides some automatic competition as one or
  592. Xmore computer players.
  593. XOne such player,
  594. X.BR \s-2CUBEX\s+2 ,
  595. Xplays in every game,
  596. Xbut depending on the number of human players and some random factors,
  597. Xone or more additional computer players also may join.
  598. XEach computer player has its own distinct playing style that
  599. Xdoes not vary from game to game.
  600. XEach may also have a preference for
  601. X.I Standard
  602. Xor
  603. X.I Blitz
  604. Xmode games, though most have no preference.
  605. XTheir competence ranges from mildly so to expert,
  606. Xbut no matter how it may seem at times,
  607. Xthe game is not rigged in their favor.
  608. X.SH "THE SCORE FILE"
  609. XThe cube server keeps a score file that contains information about each
  610. Xhuman and computer player that has played
  611. X.I cubes
  612. Xon that system.
  613. XRegardless of the name chosen to display on the scoreboard,
  614. Xhuman players are recorded in the score file by login name.
  615. XComputer players are recorded by their one and only name.
  616. XAn auxiliary program called
  617. X.IR cuberank (6)
  618. Xis provided to display the contents of this system's
  619. X.I cubes
  620. Xscore file.
  621. X.PP
  622. XAs a convenient mechanism for keeping track of your personal ranking
  623. Xhistory,
  624. X.I cubes
  625. Xwill append your current ranking information to the file ".cubehist"
  626. Xin your home directory
  627. X(as specified by the
  628. X.B HOME
  629. Xenvironment variable)
  630. Xafter each game played to completion.
  631. X.SH "JOINING A GAME IN PROGRESS"
  632. XA person may join a game in progress as either a new player,
  633. Xor as an unnamed observer.
  634. XIf the game is near ending
  635. X(defined as the high score being 75% or more of the
  636. X.IR Win \  Score ),
  637. Xor if the
  638. X.RB ` \-p '
  639. Xcommand line option was not specified,
  640. Xyou will be added to the game as an observer.
  641. XWhen the current game ends,
  642. Xwill be asked whether you wish to play in the next game.
  643. XYou can join the game in progress with the
  644. X.RB ` g '
  645. Xcommand.
  646. XIf you choose to play,
  647. Xyou will be added as an active player at the end of the current round
  648. Xand you will appear as the first player in the turn order.
  649. XSince coming into a game late with no points could ruin your ranking,
  650. Xthe cube server will give you an initial score
  651. Xthat is 500 points less than the lowest score,
  652. Xbut you still must meet the
  653. X.I On Board
  654. Xturn point requirement to begin advancing your score.
  655. X.PP
  656. XComputer players will sometimes join particularly close games in progress.
  657. XChalk it up to love of excitement, if you must.
  658. X.SH "QUITTING EARLY"
  659. XIt is important to note that quitting a game before it ends
  660. Xwill probably result in a low score being added to your record,
  661. Xpossibly lowering your ranking against other players.
  662. XExcept as described in the next paragraph,
  663. Xif you quit a game before you get
  664. X.IR On \  Board ,
  665. Xyour average game point value,
  666. X.I GamPt
  667. X(see
  668. X.IR cuberank (6)),
  669. Xis penalized by being adjusted to the value you would have had if
  670. Xyou had stayed in the game and lost with a score of half your average.
  671. XThis adjustment is done by subtracting points from your cumulative point record;
  672. Xyour game count and other records are not altered.
  673. XExcept as described in the next paragraph,
  674. Xif you quit a game when you are
  675. X.IR On \  Board ,
  676. Xyour current score is recorded in the score file.
  677. X.PP
  678. XIn games with more than one human player,
  679. Xit is possible that a computer proxy will take over for
  680. Xa player that quits the game early.
  681. XThe chances of this happening are 20% if the exiting player is not
  682. X.IR On \  Board ,
  683. Xand 60% if the player is
  684. X.IR On \  Board .
  685. XProxies play with a somewhat erratic style,
  686. Xso they should be almost indiscernible from humans.
  687. XNo notice is given to anybody when a proxy takes over.
  688. XThe absentee player will be credited with the score that the proxy
  689. Xmanages to attain by game end (for good or bad).
  690. X.PP
  691. XThe cube server will not conduct a game that has no human players.
  692. XTo meet that requirement,
  693. Xwhen the only human player quits the game,
  694. Xno proxy is assigned and the game is ended at that point.
  695. XThe human player's score will be recorded in the score file
  696. Xonly if that player was 
  697. X.I On Board
  698. Xat the time of quitting.
  699. XThe scores of the computer players (proxies are included in this category)
  700. Xare not recorded,
  701. Xregardless of their
  702. X.I On Board
  703. Xstatus.
  704. XIn short, if the only human player quits a game before getting
  705. X.IR On \  Board ,
  706. Xno record of the game is added to the score file,
  707. Xalthough the human player will suffer the penalty described above.
  708. X.PP
  709. XUnlike previous versions of this game,
  710. Xthere is no point at which it is safe to quit early.
  711. XThere is always a risk, if not a certainty, of being penalized for quitting.
  712. X.PP
  713. XSome computer players, like cowardly human players,
  714. Xquit rather than get
  715. X.I On Board
  716. Xvery far behind,
  717. Xsuffering the same penalty that humans do when they quit.
  718. XOnce the high score has reached 25% of the
  719. X.IR Win \  Score ,
  720. Xbefore each turn, computer players that are not
  721. X.I On Board
  722. Xdecide whether to continue in the game.
  723. XIf the computer needs more points to reach its average
  724. Xthan the leader needs to win, the computer may quit.
  725. X.BR \s-2CUBEX\s+2 ,
  726. Xbeing oblivious to other players,
  727. Xand possessing a singularly strong desire to play
  728. X.IR cubes ,
  729. Xwill not quit the game.
  730. XIt should be noted that proxy players also will not quit a game.
  731. X.SH AUTOPILOT
  732. XA game of
  733. X.I cubes
  734. Xusually takes about 20 minutes to play.
  735. XStrangely, starting a game of
  736. X.I cubes
  737. Xseems to generate phone calls and visits from associates demanding
  738. Xattention.
  739. XTo allow players to deal with interruptions,
  740. Xthere is an autopilot mechanism provided.
  741. XThe command to invoke the autopilot is
  742. X.RB ` x '
  743. Xand can be used during your turn, or asynchronously.
  744. XYou'll probably want to suspend
  745. X.I cubes
  746. Xwith a control-Z once you engage the autopilot.
  747. XThe autopilot will play for you until you type
  748. X.RB ` g '
  749. Xfor go.
  750. X.PP
  751. XIt should be noted that the autopilot is not a very good player.
  752. X.SH MISCELLANY
  753. XOn some systems,
  754. Xit is possible to tell the state of the cube server by doing a
  755. X.IR ps (1)
  756. X(or something similar) on it.
  757. XIf a game is in progress,
  758. Xthe command line of the process will have been altered to
  759. Xshow the number of players, turn number, high score, and player up.
  760. XEven more useful is an auxiliary program, called
  761. X.IR cubestat (6),
  762. Xthat produces a more detailed report of the server status.
  763. X.PP
  764. XThe last player in the turn order has somewhat of an advantage.
  765. XTherefore,
  766. X.I cubes
  767. Xuses player order as a reward for good playing.
  768. XWhen a game is begun after the cube server has been idle,
  769. Xthe players will be ordered in reverse-rank order (top-ranked player last).
  770. XIn subsequent games, players will be ordered based on the score from
  771. Xthe previous game, with best score last.
  772. XAny player that joins a game in progress,
  773. Xor begins in a game that contains players from a just ended game,
  774. Xis put at the beginning of the turn order.
  775. XIf more than one such player enters a game on the same turn,
  776. Xthe new players will be added to the beginning of the turn order,
  777. Xbut, amongst themselves, will be ordered in reverse-rank order.
  778. X.PP
  779. XA control-Z (or whatever your suspend character is) will cause
  780. X.I cubes
  781. Xto return you to the shell,
  782. Xassuming that your shell supports job control.
  783. XThe
  784. X.I cubes
  785. Xprocess will continue to run silently in the background,
  786. Xbut will beep your terminal whenever you are being prompted.
  787. XBring
  788. X.I cubes
  789. Xback to the foreground (usually by typing
  790. X.RB ` fg ')
  791. Xto resume play at the current point in the game.
  792. X.PP
  793. XShould the screen become garbled,
  794. Xit can be redrawn by typing control-L
  795. Xor, if you prefer, your terminal reprint character (usually control-R).
  796. XThere may be a slight delay before
  797. X.I cubes
  798. Xresponds to the screen redraw request.
  799. X.PP
  800. XTo keep the game moving,
  801. Xthere is a sixty second timeout on every question asked by
  802. X.IR cubes .
  803. XThe program will beep your terminal bell every twenty
  804. Xseconds until the timeout is reached.
  805. XAlthough the program tries to handle timeouts gracefully
  806. Xand may engage the autopilot automatically
  807. Xif you wait too long to roll.
  808. X.PP
  809. XWhen rerolling,
  810. Xthere are some synonyms for the four commands;
  811. Xyou may find some more convenient to type.
  812. XFor hold,
  813. Xthe synonyms are
  814. X.RB ` q '
  815. Xfor quit rolling,
  816. X.RB ` n '
  817. Xfor no (don't roll again),
  818. Xand
  819. X.RB ` . '
  820. X(period) for those who like to use a numeric keypad.
  821. XFor roll,
  822. Xthere is a synonym of
  823. X.RB ` t '
  824. Xfor throw.
  825. XFor keep there is
  826. X.RB ` s '
  827. Xfor save,
  828. Xand, for the numeric keypad crowd,
  829. X.RB ` , '
  830. X(komma, er rather, comma).
  831. X.PP
  832. XThe cube server uses a pseudorandom number generator to generate the die rolls.
  833. XUnlike real life, it is possible to see what a player would have rolled
  834. Xby looking at what the following player rolls.
  835. XFor instance, if a player debates whether to roll three dice,
  836. Xthen decides to hold, that player can check dice one, two, and three
  837. Xon the following player's roll to see what would have been rolled.
  838. XThis type of hindsight is not available in the physical world.
  839. X.PP
  840. XIf you wish to use a shell script to invoke
  841. X.IR cubes ,
  842. Xthe script must take into account that
  843. X.I cubes
  844. Xchanges the meaning of the interrupt and quit signals.
  845. XYour shell script must not respond to these signals.
  846. XOne way to accomplish this is to have your shell script
  847. X.I exec cubes
  848. X(see
  849. X.IR sh (1)),
  850. Xthus avoiding the problem altogether,
  851. Xsince the shell script will ``vanish'' at the point of the
  852. X.IR exec .
  853. XBourne or Korn shell example:
  854. X.PP
  855. X.nf
  856. X    exec /usr/games/cubes "$@"
  857. X.fi
  858. X.PP
  859. XIf you have more processing that you wish to do after
  860. X.I cubes
  861. Xexits, the
  862. X.I exec
  863. Xmethod will not suffice.
  864. XInstead, your shell script must
  865. X.I trap
  866. Xand do nothing with (but NOT ignore)
  867. Xthe two signals in question.
  868. XBourne or Korn shell example:
  869. X.PP
  870. X.nf
  871. X    trap : INT QUIT
  872. X    /usr/games/cubes "$@"
  873. X    /usr/games/cuberank -n5
  874. X.fi
  875. X.PP
  876. X(If you prefer to write your shell scripts using
  877. X.IR csh (1),
  878. Xyou're on your own...)
  879. X.SH HISTORY
  880. XThis game is an adaptation of a ``traditional'' dice game the author learned
  881. Xfrom a friend twelve years before writing this program.
  882. XIf the name of the game was learned at the time, it since has been forgotten.
  883. XThe name
  884. X.I cubes
  885. Xwas coined as the name of this computer implementation of the game.
  886. XIn the process of fine tuning the game of
  887. X.IR cubes ,
  888. Xsome liberties have been taken with the rules as learned.
  889. XWhat follows is a list of differences between
  890. X.I cubes
  891. Xand the original (name unknown) dice game.
  892. X.IP (1) 4
  893. XThe 500 point
  894. X.I Off Board
  895. Xthreshold did not exist in the original.
  896. XNo minimum turn score was necessary to cross
  897. X.I Win Score
  898. Xpoints.
  899. X.IP (2)
  900. XThe 250 point
  901. X.I Win Margin
  902. Xdid not exist in the original.
  903. XThe player with the highest score (at or above
  904. X.IR Win \  Score ,
  905. Xof course)
  906. Xat the end of the round was the winner.
  907. X.IP (3)
  908. XThe scoring combination of
  909. X.I Four of a Kind
  910. Xdid not exist in the original.
  911. X.IP (4)
  912. XThe scoring combination
  913. X.I Small Straight
  914. Xdid not exist in the original.
  915. X.IP (5)
  916. XIn the original,
  917. X.I Five of a Kind
  918. Xcould be scored only in ones or fives.
  919. X(Even in
  920. X.IR cubes ,
  921. Xscoring
  922. X.I Five of a Kind
  923. Xin anything other than ones or fives is rare.)
  924. X.IP (6)
  925. XScoring a
  926. X.I Straight
  927. Xin multiple rolls has been added by popular demand.
  928. XIt turns out that this combination adds quite a bit
  929. Xmore strategy to the game.
  930. X(Hint: compute the probabilities.)
  931. X.IP (7)
  932. XIn the original game, there were no computer players!
  933. X.IP (8)
  934. XQuitting as a tactic to preserve ranking is a seemingly
  935. Xunavoidable side effect of this implementation of the game.
  936. XIn the real life dice game, people usually don't up and quit,
  937. Xeven if they start out way behind.
  938. XThe quitting penalty is the fairest way, so far devised,
  939. Xto mimic the peer pressure of a real life game.
  940. X.SH "ENVIRONMENT VARIABLES"
  941. X.DT
  942. X.nf
  943. XHOME        home directory
  944. XUSER        login name
  945. XCUBEHIST    default ranking history file
  946. XCUBEHOST    default server host
  947. XCUBENAME    default player name
  948. X.fi
  949. X.SH FILES
  950. X.DT
  951. X.nf
  952. X$HOME/.cubehist    user's ranking history file
  953. X.fi
  954. X.SH "SEE ALSO"
  955. Xcubes(6), cuberank(6), cubestat(6), cubeserver(6), ps(1), sh(1), termcap(5)
  956. X.SH AUTHOR
  957. XGreg Paris <gmp@rayssd.ray.com>
  958. END_OF_FILE
  959. if test 26844 -ne `wc -c <'cubes.long.6'`; then
  960.     echo shar: \"'cubes.long.6'\" unpacked with wrong size!
  961. fi
  962. # end of 'cubes.long.6'
  963. fi
  964. if test -f 'moniker.c' -a "${1}" != "-c" ; then 
  965.   echo shar: Will not clobber existing file \"'moniker.c'\"
  966. else
  967. echo shar: Extracting \"'moniker.c'\" \(3417 characters\)
  968. sed "s/^X//" >'moniker.c' <<'END_OF_FILE'
  969. X/*    vi:set sw=4 ts=4: */
  970. X#ifndef    lint
  971. Xstatic char    sccsid[] = "@(#)moniker.c 5.1 (G.M. Paris) 89/01/22";
  972. X#endif    lint
  973. X
  974. X/*
  975. X**
  976. X**    cubes 5.1  Copyright 1989 Gregory M. Paris
  977. X**        Permission granted to redistribute on a no charge basis.
  978. X**        All other rights are reserved.
  979. X**
  980. X*/
  981. X
  982. X#include    <stdio.h>
  983. X#include    <syslog.h>
  984. X#include    <strings.h>
  985. X#include    "cubes.h"
  986. X
  987. X#ifdef    lint
  988. X#ifndef    MONFILE
  989. X#define    MONFILE    "dummy-monfile"
  990. X#endif    MONFILE
  991. X#endif    lint
  992. X
  993. Xstruct mon {
  994. X    char        m_name[NAMELEN];
  995. X    struct mon *m_next;
  996. X};
  997. X
  998. X/*
  999. X**    seed: names to seed the moniker list
  1000. X*/
  1001. Xstatic struct mon    seed[]    = {
  1002. X    { "Ronald Reagan",        seed+ 1 },
  1003. X    { "Nancy Reagan",        seed+ 2 },
  1004. X    { "George Bush",        seed+ 3 },
  1005. X    { "Barbara Bush",        seed+ 4 },
  1006. X    { "Mikhail Gorbachev",    seed+ 5 },
  1007. X    { "Raisa Gorbachev",    seed+ 6 },
  1008. X    { "Benny Hill",            seed+ 7 },
  1009. X    { "Margaret Thatcher",     seed+ 8 },
  1010. X    { "Piotr Chekov",         seed+ 9 },
  1011. X    { "Jamie Finney",         seed+10 },
  1012. X    { "Touche Turtle",         seed+11 },
  1013. X    { "Judy Jetson",         seed+12 },
  1014. X    { "Cobb Anderson",         seed+13 },
  1015. X    { "Della Taze",         seed+14 },
  1016. X    { "Mickey Mouse",         seed+15 },
  1017. X    { "Minnie Mouse",         seed+16 },
  1018. X    { "Edison Carter",         seed+17 },
  1019. X    { "Theora Jones",        0 },
  1020. X};
  1021. X
  1022. Xstatic int            seedcnt    = sizeof seed / sizeof seed[0];
  1023. Xstatic struct mon  *monlist    = 0;
  1024. Xstatic int            moncnt    = 0;
  1025. X
  1026. Xextern char           *malloc();
  1027. Xextern char           *fgets();
  1028. Xextern computer       *compbyname();
  1029. X
  1030. X/*
  1031. X**    savename: add a name to the moniker list and save the new list
  1032. X*/
  1033. Xsavename(name)
  1034. Xchar   *name;
  1035. X{
  1036. X    register struct mon       *m;
  1037. X    FILE                   *fp;
  1038. X
  1039. X    if(monlist == 0)
  1040. X        readmonfile();
  1041. X
  1042. X    if(strlen(name) < 5)        /* small names are boring */
  1043. X        return;
  1044. X    if(compbyname(name) != 0)    /* don't save computer names */
  1045. X        return;
  1046. X    
  1047. X    /*
  1048. X    **    Check for duplicate while finding the end of the list.
  1049. X    */
  1050. X    for(m = monlist;;m = m->m_next) {
  1051. X        if(strncmp(name, m->m_name, NAMELEN) == 0)
  1052. X            return;
  1053. X        if(m->m_next == 0)
  1054. X            break;
  1055. X    }
  1056. X
  1057. X    /*
  1058. X    **    Add the new name to the end of the list.
  1059. X    */
  1060. X    if((m->m_next = (struct mon *)malloc(sizeof *m)) == 0) {
  1061. X        syslog(LOG_WARNING, "savename: out of memory");
  1062. X        return;
  1063. X    }
  1064. X    m = m->m_next;
  1065. X    m->m_next = 0;
  1066. X    strncpy(m->m_name, name, NAMELEN);
  1067. X    m->m_name[NAMELEN-1] = '\0';
  1068. X    ++moncnt;
  1069. X
  1070. X    /*
  1071. X    **    Append the new name to the monikers file.
  1072. X    */
  1073. X    (void) umask(022);
  1074. X    if((fp = fopen(MONFILE, "a")) == 0) {
  1075. X        syslog(LOG_WARNING, "savename: fopen(%s,a): %m", MONFILE);
  1076. X        return;
  1077. X    }
  1078. X    fprintf(fp, "%s\n", m->m_name);
  1079. X    (void) fclose(fp);
  1080. X}
  1081. X
  1082. X/*
  1083. X**    moniker: randomly select a name from the moniker list
  1084. X*/
  1085. Xchar *
  1086. Xmoniker()
  1087. X{
  1088. X    register struct mon       *m;
  1089. X    register int            n;
  1090. X
  1091. X    if(monlist == 0)
  1092. X        readmonfile();
  1093. X
  1094. X    n = randint(moncnt) - 1;
  1095. X    for(m = monlist;n > 0 && m->m_next != 0;--n, m = m->m_next)
  1096. X        ;
  1097. X    
  1098. X    return m->m_name;
  1099. X}
  1100. X
  1101. X/*
  1102. X**    readmonfile: seed the monikers list then read in the monikers file
  1103. X*/
  1104. Xreadmonfile()
  1105. X{
  1106. X    register struct mon       *m;
  1107. X    register FILE           *fp;
  1108. X    char                   *s, line[2*NAMELEN];
  1109. X
  1110. X    monlist = &seed[0];
  1111. X    moncnt = seedcnt;
  1112. X
  1113. X    if((fp = fopen(MONFILE, "r")) == 0) {
  1114. X        syslog(LOG_WARNING, "readmonfile: fopen(%s,r): %m", MONFILE);
  1115. X        return;
  1116. X    }
  1117. X
  1118. X    for(m = monlist;m->m_next != 0;++m)
  1119. X        ;
  1120. X
  1121. X    while(fgets(line, sizeof line, fp) != 0) {
  1122. X        if(*(s = &line[strlen(line)-1]) == '\n')
  1123. X            *s = '\0';
  1124. X        if((m->m_next = (struct mon *)malloc(sizeof *m)) == 0) {
  1125. X            syslog(LOG_WARNING, "readmonfile: out of memory");
  1126. X            return;
  1127. X        }
  1128. X        m = m->m_next;
  1129. X        m->m_next = 0;
  1130. X        strncpy(m->m_name, line, NAMELEN);
  1131. X        m->m_name[NAMELEN-1] = '\0';
  1132. X        ++moncnt;
  1133. X    }
  1134. X
  1135. X    (void) fclose(fp);
  1136. X}
  1137. END_OF_FILE
  1138. if test 3417 -ne `wc -c <'moniker.c'`; then
  1139.     echo shar: \"'moniker.c'\" unpacked with wrong size!
  1140. fi
  1141. # end of 'moniker.c'
  1142. fi
  1143. if test -f 'tempers.c' -a "${1}" != "-c" ; then 
  1144.   echo shar: Will not clobber existing file \"'tempers.c'\"
  1145. else
  1146. echo shar: Extracting \"'tempers.c'\" \(21222 characters\)
  1147. sed "s/^X//" >'tempers.c' <<'END_OF_FILE'
  1148. X/*    vi:set sw=4 ts=4: */
  1149. X#ifndef    lint
  1150. Xstatic char    sccsid[] = "@(#)tempers.c 5.1 (G.M. Paris) 89/01/22";
  1151. X#endif    lint
  1152. X
  1153. X/*
  1154. X**
  1155. X**    cubes 5.1  Copyright 1989 Gregory M. Paris
  1156. X**        Permission granted to redistribute on a no charge basis.
  1157. X**        All other rights are reserved.
  1158. X**
  1159. X*/
  1160. X
  1161. X#include    <syslog.h>
  1162. X#include    "cubes.h"
  1163. X
  1164. Xextern unsigned        nhist;
  1165. Xextern history       *hist;
  1166. Xextern int            winscore;
  1167. Xextern int            turnnum;
  1168. Xextern boolean        jokermode;
  1169. Xextern player        plr[];
  1170. Xextern double        ziprisk();
  1171. Xextern int            highscore();
  1172. Xextern int            closescore();
  1173. Xextern int            winner();
  1174. Xextern long            histavgplr();
  1175. X
  1176. X#define    P_MAXROLL    (P_ACEMULT * P_AOKMULT)    /* largest single roll */
  1177. X
  1178. X/*
  1179. X**    atbreakeven: returns True if player has reached the quit-penalty
  1180. X**        break-even point (roughly half of player's point average)
  1181. X**        or can be expected to reach it before the game ends
  1182. X*/
  1183. Xboolean
  1184. Xatbreakeven(comp, mscore, hscore)
  1185. Xint        comp, mscore, hscore;
  1186. X{
  1187. X    long    half, need;
  1188. X
  1189. X    if((half = histavgplr(comp)) == 0)            /* no average */
  1190. X        return True;                            /* passed it, right? */
  1191. X    half = (half * winscore) / (2 * WINSCORE);    /* derate and half */
  1192. X    if((need = half - mscore) <= 0)                /* passed it? */
  1193. X        return True;
  1194. X    if(winscore - hscore > 2 * need)            /* probably can reach it? */
  1195. X        return True;
  1196. X    return False;                                /* not yet */
  1197. X}
  1198. X
  1199. X/*
  1200. X**    robot: just plays the expectations and ignores other players, etc.
  1201. X*/
  1202. X/*ARGSUSED*/
  1203. Xstatic boolean
  1204. Xrobot(comp, stay, xpct, pd)
  1205. Xint            comp, stay, xpct;
  1206. Xdiceset       *pd;
  1207. X{
  1208. X    /*
  1209. X    **    Don't roll if there's no advantage.
  1210. X    */
  1211. X    return (xpct <= stay) ? False : True;
  1212. X}
  1213. X
  1214. X/*
  1215. X**    xx_antsy: gets antsy when it gets behind; uses supplied tracking function
  1216. X**        a little bit more conservative than robot when ahead
  1217. X*/
  1218. X/*ARGSUSED*/
  1219. Xstatic boolean
  1220. Xxx_antsy(comp, stay, xpct, pd, track)
  1221. Xint            comp, stay, xpct;
  1222. Xdiceset       *pd;
  1223. Xint          (*track)();
  1224. X{
  1225. X    int        mscore;
  1226. X    int        hscore, hc;
  1227. X    double    livefac;
  1228. X
  1229. X#define    TOOLITTLE    (2 * P_ACE)
  1230. X#define    GAINFAC        1.1
  1231. X#define    WAYBEHIND    ((P_MAXROLL * winscore) / WINSCORE)
  1232. X#define    CLOSE        WINMARGIN
  1233. X#define    AVGTURN        400            /* empirically derived */
  1234. X#define    SANITY        0.40
  1235. X
  1236. X    /*
  1237. X    **    Avoid starting out too far in the hole by not getting on board
  1238. X    **    way behind -- the leave-the-game algorithm will eventually "save"
  1239. X    **    us, but we pay a price.  We know what the price is, so if we
  1240. X    **    reach the break-even point, we hold.
  1241. X    */
  1242. X    mscore = plr[comp].p_score + stay;
  1243. X    if(plr[comp].p_onboard == False /* && stay >= ONBOARD */) {
  1244. X        hscore = highscore(comp, (int *)0);    /* not (*track) */
  1245. X        if(hscore - mscore > WAYBEHIND) {
  1246. X            if(atbreakeven(comp, mscore, hscore) == True)
  1247. X                return False;                /* hold */
  1248. X            return True;                    /* desperation */
  1249. X        }
  1250. X    }
  1251. X
  1252. X    /*
  1253. X    **    Never stop with too little points.
  1254. X    */
  1255. X    if(stay <= TOOLITTLE)
  1256. X        return True;
  1257. X    
  1258. X    /*
  1259. X    **    If there's gain to be had, roll again.
  1260. X    */
  1261. X    if(xpct > (int)(GAINFAC * stay))
  1262. X        return True;
  1263. X
  1264. X    /*
  1265. X    **    Find our score and the score we're tracking.  If we're ahead
  1266. X    **    or close, then don't reroll.  Our definition of close depends
  1267. X    **    on whether the leader has already taken its turn this round.
  1268. X    */
  1269. X    hscore = (*track)(comp, &hc);
  1270. X    if(hc < comp) {        /* leader has taken turn */
  1271. X        if(hscore - mscore <= CLOSE)
  1272. X            return False;
  1273. X    } else {            /* leader's turn still to come */
  1274. X        if(hscore - mscore <= CLOSE - AVGTURN)
  1275. X            return False;
  1276. X    }
  1277. X
  1278. X    /*
  1279. X    **    Calculate the expectation value we can live with.
  1280. X    */
  1281. X    livefac = GAINFAC - (double)(hscore - mscore) / winscore;
  1282. X    if(livefac < SANITY)
  1283. X        livefac = SANITY;
  1284. X    if(xpct > (int)(livefac * stay))
  1285. X        return True;
  1286. X    
  1287. X    return False;
  1288. X
  1289. X#undef    TOOLITTLE
  1290. X#undef    GAINFAC
  1291. X#undef    WAYBEHIND
  1292. X#undef    CLOSE
  1293. X#undef    AVGTURN
  1294. X#undef    SANITY
  1295. X}
  1296. X
  1297. X/*
  1298. X**    antsy: gets antsy when it gets behind; tracks leader
  1299. X*/
  1300. Xstatic boolean
  1301. Xantsy(comp, stay, xpct, pd)
  1302. Xint            comp, stay, xpct;
  1303. Xdiceset       *pd;
  1304. X{
  1305. X    return xx_antsy(comp, stay, xpct, pd, highscore);
  1306. X}
  1307. X
  1308. X/*
  1309. X**    tracker: same as antsy but tracks highest close score rather than higest
  1310. X*/
  1311. Xstatic boolean
  1312. Xtracker(comp, stay, xpct, pd)
  1313. Xint            comp, stay, xpct;
  1314. Xdiceset       *pd;
  1315. X{
  1316. X    return xx_antsy(comp, stay, xpct, pd, closescore);
  1317. X}
  1318. X
  1319. X/*
  1320. X**    chicken: gets scared when it has lots of points in hand
  1321. X**        doesn't care about expectation or other players
  1322. X**        also chickens out as soon as it thinks it has won
  1323. X**        won't get on board if high score is out of range
  1324. X*/
  1325. X/*ARGSUSED*/
  1326. Xstatic boolean
  1327. Xchicken(comp, stay, xpct, pd)
  1328. Xint            comp, stay, xpct;
  1329. Xdiceset       *pd;
  1330. X{
  1331. X    int        mscore, hscore, hc;
  1332. X    int        atrisk, maxrisk;
  1333. X    int        range, magic;
  1334. X
  1335. X#define    OUTRNG        ((P_STRAIGHT * winscore) / WINSCORE)
  1336. X#define    AVGTURN        375        /* empirically, a bit low */
  1337. X
  1338. X    /*
  1339. X    **    We have the opportunity to get on board if we quit.  We hold
  1340. X    **    if the high score is not out of range.  We roll again if we
  1341. X    **    have no average, thus cannot be penalized.  We hold if we've
  1342. X    **    reached the break-even point.  Otherwise, roll again.
  1343. X    */
  1344. X    if(plr[comp].p_onboard == False /* && stay >= ONBOARD */) {
  1345. X        mscore = plr[comp].p_score + stay;
  1346. X        hscore = highscore(comp, &hc);
  1347. X        if(hc > comp)
  1348. X            hscore += AVGTURN;
  1349. X        if(hscore - mscore < OUTRNG)
  1350. X            return False;                /* close enough, hold! */
  1351. X        if(atbreakeven(comp, mscore, hscore) == True)
  1352. X            return False;                /* too risky to roll */
  1353. X        return True;                    /* desperation... */
  1354. X    }
  1355. X    
  1356. X    /*
  1357. X    **    If the leader's turn has already been taken, then if we
  1358. X    **    can win, hold.  If the leader has yet to take its turn,
  1359. X    **    if we can block it from winning, hold.  Adjust hscore
  1360. X    **    here for leader's predicted turn.
  1361. X    */
  1362. X    if((mscore = plr[comp].p_score + stay) >= winscore) {
  1363. X        hscore = highscore(comp, &hc);
  1364. X        if(hc < comp) {                            /* leader had turn */
  1365. X            if(mscore - hscore >= WINMARGIN)    /* can we win? */
  1366. X                return False;
  1367. X        } else {                                /* leader's turn to come */
  1368. X            hscore += AVGTURN;                    /* predict future */
  1369. X            if(hscore - mscore < WINMARGIN)        /* can we block? */
  1370. X                return False;
  1371. X        }
  1372. X    }
  1373. X
  1374. X    /*
  1375. X    **    Our behavior is dependent on our mood.
  1376. X    */
  1377. X    switch(plr[comp].p_mood) {
  1378. X    case 2: magic = P_FIVE / 2; break;
  1379. X    case 3: magic = P_FIVE * 2; break;
  1380. X    default:magic = P_FIVE; break;
  1381. X    }
  1382. X
  1383. X    /*
  1384. X    **    We are conservative when close, getting more desperate
  1385. X    **    as we get further behind.  We get a little wild when
  1386. X    **    we're ahead too.
  1387. X    */
  1388. X    atrisk = (int)(stay * ziprisk(pd));
  1389. X    if((range = (mscore - hscore + 1) / WINMARGIN) <= 0)
  1390. X        maxrisk = ((1 - range) * magic);    /* not winning */
  1391. X    else
  1392. X        maxrisk = (range * magic) / 3;        /* winning */
  1393. X    if(maxrisk > 4 * magic)
  1394. X        maxrisk = 4 * magic;
  1395. X
  1396. X    if(atrisk > maxrisk)
  1397. X        return False;
  1398. X
  1399. X    return True;
  1400. X
  1401. X#undef    OUTRNG
  1402. X#undef    AVGTURN
  1403. X}
  1404. X
  1405. X/*
  1406. X**    gambler: cautious sometimes, not so others
  1407. X**        stops when it gets on board unless the risk is small or far behind
  1408. X**        stops when it has won or could block unless the risk is small
  1409. X**        rolls when the expectation is favorable
  1410. X**        rolls to try to stop a winner until too much at risk
  1411. X**        rolls when there's less than 50% risk and is behind and "lucky"
  1412. X*/
  1413. X/*ARGSUSED*/
  1414. Xstatic boolean
  1415. Xgambler(comp, stay, xpct, pd)
  1416. Xint            comp, stay, xpct;
  1417. Xdiceset       *pd;
  1418. X{
  1419. X    int        mscore, hscore, hc;
  1420. X    double    luck;
  1421. X
  1422. X#define    SMALLRISK    0.15
  1423. X#define    EVENODDS    0.50
  1424. X#define    FARBEHIND    (winscore / 5)
  1425. X#define    AVGTURN        (jokermode == True ? 350 : 450)
  1426. X
  1427. X    /*
  1428. X    **    Calculate our score.  Calculate the other highest score
  1429. X    **    and if the leader hasn't taken its turn yet, guess at
  1430. X    **    what that turn might amount to.
  1431. X    */
  1432. X    mscore = plr[comp].p_score + stay;
  1433. X    hscore = highscore(comp, &hc);
  1434. X    if(hc > comp)                        /* leader hasn't taken this turn */
  1435. X        hscore += AVGTURN;                /* adjust for future earnings */
  1436. X
  1437. X    /*
  1438. X    **    If we can get on board, we roll again anyway if we're
  1439. X    **    far behind.  Otherwise, we hold unless it's really tempting.
  1440. X    */
  1441. X    if(plr[comp].p_onboard == False /* && stay >= ONBOARD */) {
  1442. X        if(hscore - mscore > FARBEHIND) {
  1443. X            if(atbreakeven(comp, mscore, hscore) == False)
  1444. X                return True;    /* too risky to quit */
  1445. X        }
  1446. X        if(xpct > stay && ziprisk(pd) < SMALLRISK)
  1447. X            return True;
  1448. X        return False;
  1449. X    }
  1450. X    
  1451. X    /*
  1452. X    **    If we could win or block, hold unless it's really tempting.
  1453. X    */
  1454. X    if((mscore = plr[comp].p_score + stay) >= winscore) {
  1455. X        if(    (hc < comp && mscore - hscore >= WINMARGIN)        /* can win */
  1456. X        ||    (hc > comp && hscore - mscore < WINMARGIN)) {    /* can block */
  1457. X            if(xpct > stay && ziprisk(pd) < SMALLRISK)
  1458. X                return True;
  1459. X            return False;
  1460. X        }
  1461. X    }
  1462. X
  1463. X    /*
  1464. X    **    If the expectation value is better than what we've got, go ahead.
  1465. X    */
  1466. X    if(xpct > stay)
  1467. X        return True;
  1468. X
  1469. X    /*
  1470. X    **    If another player is about to win, try to stop it.  This isn't strictly
  1471. X    **    corrrect code, since we may not be the second-best score, but we can't
  1472. X    **    count on others to save us.  We give up if we risk losing too much.
  1473. X    */
  1474. X    if(hscore >= winscore && hscore - mscore >= WINMARGIN)
  1475. X        return (int)(stay * ziprisk(pd)) > P_ASMSTR ? False : True;
  1476. X    
  1477. X    /*
  1478. X    **    If we're behind, roll when the odds are favorable and we feel lucky.
  1479. X    **    We feel lucky if we've been lucky -- if we've squandered less than
  1480. X    **    half of what we've scored, then we have some luck.  If our luck
  1481. X    **    multiplied by our desperation is greater than what we'd have if
  1482. X    **    we held, then we roll.
  1483. X    */
  1484. X    if(hscore > mscore && mscore > 0 && ziprisk(pd) <= EVENODDS)
  1485. X        if((luck = 1.0 - (2.0 * plr[comp].p_squander) / mscore) > 0)
  1486. X            if(luck * (hscore - mscore) > stay)
  1487. X                return True;
  1488. X    
  1489. X    /*
  1490. X    **    Finally, don't hold with too few points.
  1491. X    */
  1492. X    return (stay < 2 * P_ACE) ? True : False;
  1493. X
  1494. X#undef    SMALLRISK
  1495. X#undef    EVENODDS
  1496. X#undef    FARBEHIND
  1497. X#undef    AVGTURN
  1498. X}
  1499. X
  1500. X/*
  1501. X**    xx_crafty:
  1502. X**        Won't get on board if too far behind.
  1503. X**        Quits when it can win, unless really tempting.
  1504. X**        Tries to roll to beat a winner.
  1505. X**        Otherwise, tries to get and protect a safelead lead
  1506. X**        becoming more daring as it gets ahead or behind,
  1507. X**        but with a limit to its stupidity.
  1508. X*/
  1509. X/*ARGSUSED*/
  1510. Xstatic boolean
  1511. Xxx_crafty(comp, stay, xpct, pd, safelead, maxgainfac, mingainfac, smallrisk)
  1512. Xint            comp, stay, xpct;
  1513. Xdiceset       *pd;
  1514. Xint            safelead;
  1515. Xdouble        maxgainfac, mingainfac, smallrisk;
  1516. X{
  1517. X    int        mscore, hscore;
  1518. X    int        live, winc;
  1519. X    double    gainfac;
  1520. X
  1521. X#define    TOOFAC    4
  1522. X
  1523. X    hscore = highscore(comp, (int *)0);
  1524. X    mscore = plr[comp].p_score + stay;
  1525. X
  1526. X    /*
  1527. X    **    We can get on board here.  If we're too far behind, and not
  1528. X    **    yet at the quit-penalty break-even point, we keep rolling.
  1529. X    **    If too risky, we hold.  Otherwise, use the usual decision function.
  1530. X    */
  1531. X    if(plr[comp].p_onboard == False /* && stay >= ONBOARD */) {
  1532. X        if(hscore - mscore > TOOFAC * safelead) {    /* too far behind */
  1533. X            if(atbreakeven(comp, mscore, hscore) == False)
  1534. X                return True;                        /* must roll */
  1535. X        }
  1536. X        if(ziprisk(pd) >= smallrisk)                /* too risky */
  1537. X            return False;                            /* must hold */
  1538. X    }
  1539. X    
  1540. X    /*
  1541. X    **    If we could win, hold unless it's really tempting.
  1542. X    */
  1543. X    if(mscore >= winscore)
  1544. X        if(mscore - hscore >= WINMARGIN && ziprisk(pd) >= smallrisk)
  1545. X            return False;
  1546. X
  1547. X    /*
  1548. X    **    If we have a winner (other than us), try to beat them, but only
  1549. X    **    if the expected gainfac is greater than or equal to mingainfac.
  1550. X    **    We try to get within WINMARGIN of the player's score,
  1551. X    **    but if their turn is after ours, we try to beat.
  1552. X    **    Assumes that hscore is winner's score (but what else?).
  1553. X    */
  1554. X    if((winc = winner()) != -1 && winc != comp)
  1555. X        if(xpct >= stay * mingainfac)
  1556. X            if(hscore - mscore >= WINMARGIN || winc > comp)
  1557. X                return True;
  1558. X
  1559. X    /*
  1560. X    **    If there's enough gain to be had, roll again.
  1561. X    */
  1562. X    if(xpct > (int)(maxgainfac * stay))
  1563. X        return True;
  1564. X
  1565. X    /*
  1566. X    **    Calculate the "instantaneous" gain factor.  Changed gainfac
  1567. X    **    calculation to use p_score when ahead, since this temperament
  1568. X    **    used to routinely squander huge rolls.
  1569. X    */
  1570. X    if(mscore < hscore)
  1571. X        gainfac = (double)(mscore - hscore - safelead) / P_MAXROLL;
  1572. X    else
  1573. X        gainfac = (double)(plr[comp].p_score - hscore - safelead) / P_MAXROLL;
  1574. X    if(gainfac < 0)
  1575. X        gainfac = -gainfac;
  1576. X    gainfac = maxgainfac - gainfac;
  1577. X    if(gainfac < mingainfac)
  1578. X        gainfac = mingainfac;
  1579. X
  1580. X    /*
  1581. X    **    Calculate the expectation value we can live with.
  1582. X    */
  1583. X    live = (int)(stay * gainfac);
  1584. X    if(xpct > live)
  1585. X        return True;
  1586. X    
  1587. X    return False;
  1588. X
  1589. X#undef    TOOFAC
  1590. X}
  1591. X
  1592. X/*
  1593. X**    crafty: call xx_crafty with original set of parameters
  1594. X*/
  1595. Xstatic boolean
  1596. Xcrafty(comp, stay, xpct, pd)
  1597. Xint            comp, stay, xpct;
  1598. Xdiceset       *pd;
  1599. X{
  1600. X    return xx_crafty(comp, stay, xpct, pd, WINMARGIN, 1.20, 0.85, 0.20);
  1601. X}
  1602. X
  1603. X/*
  1604. X**    shakey: call xx_crafty with revised set of parameters
  1605. X*/
  1606. Xstatic boolean
  1607. Xshakey(comp, stay, xpct, pd)
  1608. Xint            comp, stay, xpct;
  1609. Xdiceset       *pd;
  1610. X{
  1611. X    /*
  1612. X    **    We have four distinct moods.
  1613. X    */
  1614. X    switch(plr[comp].p_mood) {
  1615. X    case 2: return xx_crafty(comp,stay,xpct,pd, P_STRAIGHT, 1.30, 0.75, 0.10);
  1616. X    case 3: return xx_crafty(comp,stay,xpct,pd, 2*OFFBOARD, 1.30, 0.80, 0.15);
  1617. X    case 4: return xx_crafty(comp,stay,xpct,pd, OFFBOARD,   1.20, 0.85, 0.20);
  1618. X    default:return xx_crafty(comp,stay,xpct,pd, OFFBOARD,   1.30, 0.75, 0.10);
  1619. X    }
  1620. X}
  1621. X
  1622. X/*
  1623. X**    zeno: uses ratio of distance to finish over total distance
  1624. X*/
  1625. X/*ARGSUSED*/
  1626. Xstatic boolean
  1627. Xzeno(comp, stay, xpct, pd)
  1628. Xint            comp, stay, xpct;
  1629. Xdiceset       *pd;
  1630. X{
  1631. X#define    MINWANT        (WINMARGIN-1)
  1632. X#define    SANITY        (1.10)            /* fudge factor for endgame sanity */
  1633. X#define    AVGTURN        400                /* empirical */
  1634. X
  1635. X    int        hscore, mscore, hc;
  1636. X    int        lead, want;
  1637. X    double    zenofac, riskfac, wantfac;
  1638. X
  1639. X    mscore = plr[comp].p_score;                        /* ignore this turn */
  1640. X    hscore = highscore(comp, &hc);                    /* of best competitor */
  1641. X    zenofac = (double)hscore / winscore;            /* distance ratio */
  1642. X    if(hc < comp) {                                    /* leader had turn */
  1643. X        zenofac = (double)hscore                    /* distance ratio */
  1644. X                / (winscore * SANITY);
  1645. X        lead = (mscore-WINMARGIN) - hscore;            /* positive when winning */
  1646. X    } else {                                        /* leader's turn to come */
  1647. X        zenofac = (double)(hscore + AVGTURN)        /* distance ratio */
  1648. X                / (winscore * SANITY);
  1649. X        lead = (mscore-WINMARGIN)-(hscore+AVGTURN);    /* positive when winning */
  1650. X    }
  1651. X
  1652. X    if(lead > 0) {                                    /* we're winning */
  1653. X        riskfac = 0.90 + 0.35 * zenofac;            /* 0.90 - 1.25 */
  1654. X        if(xpct < (int)(riskfac * stay))            /* not willing to risk it */
  1655. X            return False;                            /* hold */
  1656. X        wantfac = 1.5 - 1.4 * zenofac;                /* 1.5 - 0.1 */
  1657. X        if((want = lead * wantfac) < MINWANT)        /* magic greed limit */
  1658. X            want = MINWANT;                            /* ... but keep moving */
  1659. X        if(stay > want)                                /* we're satisfied */
  1660. X            return False;                            /* hold */
  1661. X    }
  1662. X
  1663. X    else if(lead > -WINMARGIN) {                    /* it's a dead heat */
  1664. X        riskfac = 1.0 +  0.35 * zenofac;            /* 1.00 - 1.35 */
  1665. X        if(xpct < (int)(riskfac * stay))            /* not willing to risk it */
  1666. X            return False;                            /* hold */
  1667. X                                                    /* no greed test */
  1668. X    }
  1669. X
  1670. X    else {                                            /* we're losing */
  1671. X        riskfac = 1.1 - 0.35 * zenofac;                /* 1.1 - 0.75 */
  1672. X        if(xpct < (int)(riskfac * stay))            /* not willing to risk it */
  1673. X            return False;                            /* hold */
  1674. X        wantfac = 0.2 + 0.7 * zenofac;                /* 0.2 - 0.9 */
  1675. X        if((want = -lead * wantfac) < MINWANT)        /* magic greed limit */
  1676. X            want = MINWANT;                            /* ... but keep moving */
  1677. X        if(stay > want)                                /* we're satisfied */
  1678. X            return False;                            /* hold */
  1679. X    }
  1680. X
  1681. X    return True;                                    /* roll again */
  1682. X
  1683. X#undef    MINWANT
  1684. X#undef    SANITY
  1685. X#undef    AVGTURN
  1686. X}
  1687. X
  1688. X/*
  1689. X**    goalie: strives for four goals:
  1690. X**        winscore, 6/5ths average, 3/5ths average, and pace leader
  1691. X*/
  1692. X/*ARGSUSED*/
  1693. Xstatic boolean
  1694. Xgoalie(comp, stay, xpct, pd)
  1695. Xint            comp, stay, xpct;
  1696. Xdiceset       *pd;
  1697. X{
  1698. X    int        cuscore, stscore, hiscore, hc;
  1699. X    int        turnsleft, avscore, totneed, perturn;
  1700. X    int        toolittle, tooclose;
  1701. X    double    gainfac, avgturn;
  1702. X
  1703. X#define    WAYBEHIND    ((P_MAXROLL * winscore) / WINSCORE)
  1704. X#define    SANITY        0.50
  1705. X#define    MAXTURN        (P_ACEMULT * P_3OKMULT)
  1706. X
  1707. X    /*
  1708. X    **    Avoid starting out too far in the hole by not getting on board
  1709. X    **    way behind -- the leave-the-game algorithm will eventually "save"
  1710. X    **    us, but we pay a price.  We know what the price is, so if we
  1711. X    **    reach the break-even point, we hold.
  1712. X    */
  1713. X    cuscore = plr[comp].p_score;
  1714. X    stscore = cuscore + stay;
  1715. X    if(plr[comp].p_onboard == False /* && stay >= ONBOARD */) {
  1716. X        hiscore = highscore(comp, (int *)0);
  1717. X        if(hiscore - stscore > WAYBEHIND) {
  1718. X            if(atbreakeven(comp, stscore, hiscore) == True)
  1719. X                return False;            /* hold */
  1720. X            return True;                /* desperation */
  1721. X        }
  1722. X    }
  1723. X
  1724. X    /*
  1725. X    **    Some parameters depend on our mood.
  1726. X    */
  1727. X    switch(plr[comp].p_mood) {
  1728. X    case 2:        /* most agressive */
  1729. X        toolittle = 3 * P_ACE;
  1730. X        tooclose = P_FIVE;
  1731. X        gainfac = 1.025;
  1732. X        break;
  1733. X    case 3:        /* more agressive */
  1734. X        toolittle = 2 * P_ACE + P_FIVE;
  1735. X        tooclose = P_ACE;
  1736. X        gainfac = 1.050;
  1737. X        break;
  1738. X    default:    /* normal */
  1739. X        toolittle = 2 * P_ACE;
  1740. X        tooclose = P_ACE + P_FIVE;
  1741. X        gainfac = 1.075;
  1742. X        break;
  1743. X    }
  1744. X
  1745. X    /*
  1746. X    **    Never stop with too little points.  If there's gain to be had, roll.
  1747. X    **    If it would be insane to roll again, don't.
  1748. X    */
  1749. X    if(stay <= toolittle)
  1750. X        return True;
  1751. X    if(xpct > (int)(gainfac * stay))
  1752. X        return True;
  1753. X    if(xpct < (int)(SANITY * stay))
  1754. X        return False;
  1755. X    
  1756. X    /*
  1757. X    **    If we're ahead or close to the high score, don't reroll.  Definition
  1758. X    **    of close depends on whether the leader has already taken its turn this
  1759. X    **    round.  We calculate the leader's average turn for use here or below.
  1760. X    */
  1761. X    if((hiscore = highscore(comp, &hc)) == 0)
  1762. X        return False;
  1763. X    if(hc < comp) {
  1764. X        if(hiscore - stscore <= tooclose)
  1765. X            return False;
  1766. X        avgturn = (double)hiscore / (turnnum + 1);
  1767. X    } else {
  1768. X        avgturn = (double)hiscore / turnnum;
  1769. X        if(hiscore - stscore <= tooclose - (int)avgturn)
  1770. X            return False;
  1771. X    }
  1772. X    if(avgturn < P_ACE)                /* too low to believe */
  1773. X        avgturn = P_ACE;
  1774. X    else if(avgturn > P_STRAIGHT)    /* too high to believe */
  1775. X        avgturn = P_STRAIGHT;
  1776. X    
  1777. X    /*
  1778. X    **    We're behind, so it's a race to one of our goals.  We estimate how many
  1779. X    **    turns left in the game based on the leader's average turn.  From that,
  1780. X    **    we figure out what we need per turn to reach a reasonable goal.
  1781. X    **    If we've got that much, we hold, otherwise we roll again.
  1782. X    */
  1783. X    if((turnsleft = (winscore - hiscore) / avgturn) <= 0)
  1784. X        turnsleft = 1;
  1785. X    
  1786. X    /*
  1787. X    **    Primary goal: strive for winscore.
  1788. X    */
  1789. X    if((totneed = winscore - cuscore) <= 0)
  1790. X        goto pace;
  1791. X    if((perturn = totneed / turnsleft) <= MAXTURN)
  1792. X        return (stay >= perturn) ? False: True;
  1793. X
  1794. X    /*
  1795. X    **    Calculate our historical average score.
  1796. X    */
  1797. X    if((avscore = histavgplr(comp)) == 0)            /* no record */
  1798. X        avscore = (3 * WINSCORE) / 4;                /* fake one */
  1799. X    avscore = (avscore * winscore) / WINSCORE;        /* derate */
  1800. X
  1801. X    /*
  1802. X    **    Secondary goal: strive for 6/5ths of average.
  1803. X    */
  1804. X    if((totneed = (6 * avscore) / 5 - cuscore) <= 0)
  1805. X        goto pace;
  1806. X    if((perturn = totneed / turnsleft) <= MAXTURN)
  1807. X        return (stay >= perturn) ? False: True;
  1808. X
  1809. X    /*
  1810. X    **    Tertiary goal: strive for 3/5ths of average.
  1811. X    */
  1812. X    if((totneed = (3 * avscore) / 5 - cuscore) <= 0)
  1813. X        goto pace;
  1814. X    if((perturn = totneed / turnsleft) <= MAXTURN)
  1815. X        return (stay >= perturn) ? False: True;
  1816. X
  1817. X    /*
  1818. X    **    Last resort: try to keep ahead of leader.
  1819. X    **    Else, keep moving at an arbitrary pace.
  1820. X    */
  1821. Xpace:
  1822. X    if((totneed = hiscore + WINMARGIN - cuscore) > 0)
  1823. X        if((perturn = totneed / turnsleft) <= MAXTURN)
  1824. X            return (stay >= perturn) ? False: True;
  1825. X    return (stay >= 2 * P_ACE) ? False : True;
  1826. X
  1827. X#undef    WAYBEHIND
  1828. X#undef    SANITY
  1829. X#undef    MAXTURN
  1830. X}
  1831. X
  1832. X/*
  1833. X**    best: use the temperament currently ranked best
  1834. X*/
  1835. Xstatic boolean
  1836. Xbest(comp, stay, xpct, pd)
  1837. Xint            comp, stay, xpct;
  1838. Xdiceset       *pd;
  1839. X{
  1840. X    static history       *phist    = 0;
  1841. X    static computer       *last    = 0;
  1842. X    register int        n;
  1843. X    extern temper        te_best;
  1844. X    extern computer       *pkamelion;
  1845. X
  1846. X    /*
  1847. X    **    If this is our first time through, or if we're not
  1848. X    **    pointing to the same computer as last time, look
  1849. X    **    for the top ranked computer.  On occasion we might
  1850. X    **    not re-search for the top when we should, but this
  1851. X    **    should happen only rarely.
  1852. X    */
  1853. X    if(phist == 0 || last == 0 || phist->h_computer != last) {
  1854. X        last = 0;
  1855. X        for(phist = hist, n = 0;n < nhist;++n, ++phist) {
  1856. X            if(phist->h_computer == 0 || phist->h_computer == pkamelion)
  1857. X                continue;
  1858. X            if(phist->h_computer->c_temper == &te_best)
  1859. X                continue;
  1860. X            last = phist->h_computer;
  1861. X            break;
  1862. X        }
  1863. X    }
  1864. X
  1865. X    /*
  1866. X    **    If we've got a best computer, use its temperament,
  1867. X    **    else we default to using the robot temperament.
  1868. X    */
  1869. X    if(last != 0)
  1870. X        return (last->c_temper->t_func)(comp, stay, xpct, pd);
  1871. X    return robot(comp, stay, xpct, pd);
  1872. X}
  1873. X
  1874. X/*
  1875. X**    kamelion: should never be called
  1876. X*/
  1877. Xstatic boolean
  1878. Xkamelion(comp, stay, xpct, pd)
  1879. Xint            comp, stay, xpct;
  1880. Xdiceset       *pd;
  1881. X{
  1882. X    syslog(LOG_WARNING, "kamelion temperament called!");
  1883. X    return best(comp, stay, xpct, pd);
  1884. X}
  1885. X
  1886. X/*
  1887. X**    schizo: pick another temperament randomly!
  1888. X**        intended for proxy players only
  1889. X*/
  1890. Xstatic boolean
  1891. Xschizo(comp, stay, xpct, pd)
  1892. Xint            comp, stay, xpct;
  1893. Xdiceset       *pd;
  1894. X{
  1895. X    int                n;
  1896. X    extern int        tempers;
  1897. X    extern temper  *temptbl[];
  1898. X
  1899. X    hesitate(100L, 1000L);
  1900. X    plr[comp].p_mood = randint(MAXMOOD);    /* new mood every time */
  1901. X    n = randint(tempers - 1) - 1;            /* schizo last -- don't pick it */
  1902. X    return (*temptbl[n]->t_func)(comp, stay, xpct, pd);
  1903. X}
  1904. X
  1905. X/*
  1906. X**    temptbl: table of available temperaments
  1907. X*/
  1908. X
  1909. Xtemper    te_robot    = { robot,        "robot" };
  1910. Xtemper    te_antsy    = { antsy,        "antsy" };
  1911. Xtemper    te_tracker    = { tracker,    "tracker" };
  1912. Xtemper    te_chicken    = { chicken,    "chicken" };
  1913. Xtemper    te_gambler    = { gambler,    "gambler" };
  1914. Xtemper    te_crafty    = { crafty,        "crafty" };
  1915. Xtemper    te_shakey    = { shakey,        "shakey" };
  1916. Xtemper    te_zeno        = { zeno,        "zeno" };
  1917. Xtemper    te_goalie    = { goalie,        "goalie" };
  1918. Xtemper    te_best        = { best,        "best" };
  1919. Xtemper    te_schizo    = { schizo,        "schizo" };
  1920. Xtemper    te_kamelion    = { kamelion,    "kamelion" };    /* semi-dummy */
  1921. X
  1922. Xtemper       *temptbl[]    = {
  1923. X    &te_robot, &te_antsy, &te_tracker, &te_chicken, &te_gambler,
  1924. X    &te_crafty, &te_shakey, &te_zeno, &te_goalie, &te_best,
  1925. X    &te_schizo        /* te_schizo must be last */
  1926. X};
  1927. X
  1928. Xint    tempers    = sizeof temptbl / sizeof temptbl[0];
  1929. END_OF_FILE
  1930. if test 21222 -ne `wc -c <'tempers.c'`; then
  1931.     echo shar: \"'tempers.c'\" unpacked with wrong size!
  1932. fi
  1933. # end of 'tempers.c'
  1934. fi
  1935. echo shar: End of archive 3 \(of 8\).
  1936. cp /dev/null ark3isdone
  1937. MISSING=""
  1938. for I in 1 2 3 4 5 6 7 8 ; do
  1939.     if test ! -f ark${I}isdone ; then
  1940.     MISSING="${MISSING} ${I}"
  1941.     fi
  1942. done
  1943. if test "${MISSING}" = "" ; then
  1944.     echo You have unpacked all 8 archives.
  1945.     rm -f ark[1-9]isdone
  1946. else
  1947.     echo You still need to unpack the following archives:
  1948.     echo "        " ${MISSING}
  1949. fi
  1950. ##  End of shell archive.
  1951. exit 0
  1952.